/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package rentcar.services;

import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.sql.Statement;
import org.springframework.amqp.core.AmqpTemplate;
import rentcar.datareceiver.Application;
import rentcar.datareceiver.models.CarPosInfo;
import rentcar.datareceiver.models.CmdResultInfo;

/**
 * 该类为多线程类，用于服务端
 */
public class SampleServerThread implements Runnable {

        private final static String QUEUE_NAME = "hello";
        String DB_URL = "jdbc:mysql://localhost:3306/rentcar", DB_USER = "root", DB_PASSWD = "root";
        private Socket client = null;
        AmqpTemplate template = null;
        java.sql.Connection connection = null;
        Statement stmt = null;

        public SampleServerThread(Socket client) {
                this.client = client;
                //MqInit();
                //DbConnInit();
        }

        boolean SocketIsConnected(Socket socket) {
                try {
                        socket.sendUrgentData(0xFF);
                        return true;
                } catch (Exception ex) {
                        return false;
                }
        }

        //处理通信细节的静态方法，这里主要是方便线程池服务器的调用  
        public void execute(Socket client) {
                try {
                        if (client == null || !SocketIsConnected(client)) {
                                System.out.println("Got closed client!");
                                return;
                        }
                        System.out.println("Process thread started!");
                        //获取Socket的输出流，用来向客户端发送数据    
                        PrintStream out = new PrintStream(client.getOutputStream());
                        //获取Socket的输入流，用来接收从客户端发送过来的数据  
                        BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
                        boolean flag = true;
                        //超过10秒不发送数据则关闭
                        long lStartNull = 0, lNow = 0, MaxStep = 15000;

                        while (flag) {
                                if (client == null || !SocketIsConnected(client)) {
                                        System.out.println("client closed!");
                                        break;
                                }
                                System.out.println("receiving data...");
                                //接收从客户端发送过来的数据   
                                String str = buf.readLine();
                                System.out.println("Got data: " + str);

                                if (str != null && !"".equals(str)) {
                                        lStartNull = 0;
                                        System.out.println("start processing data");
                                        SampleProcessData(str);
                                        //发送到对应的客户端    
                                        // System.out.println("Sending message back...");
                                        //out.println("message received: " + str);
                                } else {
                                        if (lStartNull == 0) {
                                                lStartNull = (new Date()).getTime();
                                        }
                                        lNow = (new Date()).getTime();
                                        if (lNow - lStartNull > MaxStep && client.getInputStream().read() == -1) {
                                                System.out.println(" connection lost ...");
                                                break;
                                        }
                                }
                        }
                        out.close();
                        buf.close();
                        client.close();
                        client = null;
                        System.out.println("client closed!");
                } catch (Exception e) {
                        System.out.println("Process error! " + e.getMessage());
                }
        }

        @Override
        public void run() {
                execute(client);
        }

        void SampleProcessData(String strData) {
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String strtime = df.format(new Date());;
                //System.out.println("--- " + strtime + " ---  received: " + strData);
//解析
                String identifying = GetIdentify(strData);
                Gson gson = new Gson();

                if ("E02".equals(identifying)) {
                        //位置信息 
                        System.out.println("Got position data, save them to database");
                        //SaveToDb(cpi);
//发送至消息总线
                        //SendToMQ(strData);
                } else if ("E03".equals(identifying)) {
                        //指令应答
                        System.out.println("Got execution result, updating g_DoorSucceed.");
                        CmdResultInfo cri = gson.fromJson(strData, CmdResultInfo.class);
                        Application.g_DoorSucceed = cri.getData().getResult() == 0;
                }

        }

        String GetIdentify(String strData) {
                //获取消息标识，区分位置数据和开关门操作返回值
                String identify = "";
                int startIndex = strData.indexOf("identifying");
                char[] charArray = strData.toCharArray();
                boolean begin = false, end = false, omit = false;
                for (int i = startIndex; i < charArray.length; i++) {
                        omit = false;
                        switch (charArray[i]) {
                                case ':':
                                        begin = true;
                                        omit = true;
                                        break;
                                case ',':
                                case '}':
                                        end = true;
                                        break;
                                case '"':
                                        omit = true;
                                        break;
                                default:
                                        break;
                        }

                        if (end) {
                                break;
                        }

                        if (begin && !omit) {
                                identify += String.valueOf(charArray[i]);
                        }
                }
                return identify;
        }

}
